#ifndef SOS_TASK_H
#define SOS_TASK_H

/**
 *  A queue of asynchronous operations that will be run in between
 *  events, and on kernel ticks. Useful for asynchronous operations
 *  that are not interrupt-driven.
 */

#define SOS_TASK_SUCCESS (0)
#define SOS_TASK_YIELD   (1)
#define SOS_TASK_OOM     (2)

/* Low-priority tasks will be run on every kernel tick, e.g. long-running IO */
#define SOS_TASK_PRIORITY_LOW  (0)
/* High-priority tasks will be run ASAP, e.g. interrupt-path continuations */
#define SOS_TASK_PRIORITY_HIGH (1)

/**
 *  A task should return SOS_TASK_YIELD to remain in the queue, and
 *  SOS_TASK_SUCCESS when complete. Tasks receive the cookie from
 *  their initial registration.
 */
typedef int (*task_cb)(void *cookie);

typedef struct task {
    /* The callback to be invoked */
    task_cb cb;
    /* The cookie to be passed into cb */
    void *cookie;
    /* Fields used by libut to create a queue */
    struct task *next;
    struct task *prev;
} *task_t;

/** Add a task to the ready queue. */
int sos_task_add_ready(task_cb task, void *cookie, int priority);

/** Run all high-priority tasks */
void sos_task_run_high(void);

/** Run all low priority tasks */
void sos_task_run_low(void);

#endif // SOS_TASK_H
